"""
设备资产管理主界面
"""

import logging
from typing import Dict, Any, List
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
    QTableWidget, QTableWidgetItem, QHeaderView,
    QPushButton, QLabel, QLineEdit, QComboBox,
    QGroupBox, QSplitter, QTextEdit, QMessageBox,
    QProgressBar, QFrame, QTabWidget
)
from PyQt5.QtCore import Qt, pyqtSignal, QTimer
from PyQt5.QtGui import QFont, QColor

from src.app.modules.asset.service import AssetService
from src.app.modules.asset.ui.asset_dialog import AssetDialog
from src.app.modules.asset.utils import AssetUtils

logger = logging.getLogger(__name__)

class AssetWidget(QWidget):
    """设备资产管理主界面"""
    
    # 信号定义
    status_message = pyqtSignal(str)
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.asset_service = AssetService()
        self.asset_utils = AssetUtils()
        self.current_assets = []
        self._load_retry_count = 0  # 添加重试计数器
        self._max_retries = 10  # 最大重试次数
        
        # 初始化UI
        self.init_ui()
        
        # 设置定时刷新
        self.refresh_timer = QTimer()
        self.refresh_timer.timeout.connect(self.refresh_statistics)
        self.refresh_timer.start(30000)  # 30秒刷新一次
        
        # 使用QTimer.singleShot确保在UI完全初始化后再加载数据
        QTimer.singleShot(100, self.load_assets)
    
    def init_ui(self):
        """初始化UI界面"""
        layout = QVBoxLayout(self)
        
        # 创建分割器
        splitter = QSplitter(Qt.Vertical)
        layout.addWidget(splitter)
        
        # 上部分：统计信息和筛选
        top_widget = self.create_top_widget()
        splitter.addWidget(top_widget)
        
        # 下部分：资产列表和详情
        bottom_widget = self.create_bottom_widget()
        splitter.addWidget(bottom_widget)
        
        # 设置分割器比例
        splitter.setSizes([200, 500])
    
    def create_top_widget(self):
        """创建上部分组件"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 统计信息组
        stats_group = QGroupBox("资产统计")
        stats_layout = QGridLayout(stats_group)
        
        # 总数统计
        self.total_count_label = QLabel("0")
        self.total_count_label.setStyleSheet("font-size: 24px; font-weight: bold; color: #2196F3;")
        stats_layout.addWidget(QLabel("资产总数:"), 0, 0)
        stats_layout.addWidget(self.total_count_label, 0, 1)
        
        # 按类型统计
        self.type_stats_label = QLabel("加载中...")
        stats_layout.addWidget(QLabel("类型分布:"), 0, 2)
        stats_layout.addWidget(self.type_stats_label, 0, 3)
        
        # 按部门统计
        self.dept_stats_label = QLabel("加载中...")
        stats_layout.addWidget(QLabel("部门分布:"), 1, 0)
        stats_layout.addWidget(self.dept_stats_label, 1, 1)
        
        # 硬件资源统计
        self.resource_stats_label = QLabel("加载中...")
        stats_layout.addWidget(QLabel("硬件资源:"), 1, 2)
        stats_layout.addWidget(self.resource_stats_label, 1, 3)
        
        layout.addWidget(stats_group)
        
        # 筛选组
        filter_group = QGroupBox("筛选条件")
        filter_layout = QGridLayout(filter_group)
        
        # 资产类型筛选
        filter_layout.addWidget(QLabel("资产类型:"), 0, 0)
        self.asset_type_combo = QComboBox()
        self.asset_type_combo.addItem("全部")
        self.asset_type_combo.currentTextChanged.connect(self.apply_filters)
        filter_layout.addWidget(self.asset_type_combo, 0, 1)
        
        # 部门筛选
        filter_layout.addWidget(QLabel("部门:"), 0, 2)
        self.department_combo = QComboBox()
        self.department_combo.addItem("全部")
        self.department_combo.currentTextChanged.connect(self.apply_filters)
        filter_layout.addWidget(self.department_combo, 0, 3)
        
        # 名称搜索
        filter_layout.addWidget(QLabel("资产名称:"), 1, 0)
        self.name_search_edit = QLineEdit()
        self.name_search_edit.setPlaceholderText("输入资产名称搜索")
        self.name_search_edit.textChanged.connect(self.apply_filters)
        filter_layout.addWidget(self.name_search_edit, 1, 1)
        
        # 用途搜索
        filter_layout.addWidget(QLabel("用途描述:"), 1, 2)
        self.purpose_search_edit = QLineEdit()
        self.purpose_search_edit.setPlaceholderText("输入用途描述搜索")
        self.purpose_search_edit.textChanged.connect(self.apply_filters)
        filter_layout.addWidget(self.purpose_search_edit, 1, 3)
        
        # 操作按钮
        button_layout = QHBoxLayout()
        
        self.refresh_btn = QPushButton("刷新")
        self.refresh_btn.clicked.connect(self.load_assets)
        button_layout.addWidget(self.refresh_btn)
        
        self.export_btn = QPushButton("导出")
        self.export_btn.clicked.connect(self.export_assets)
        button_layout.addWidget(self.export_btn)
        
        self.clear_filter_btn = QPushButton("清除筛选")
        self.clear_filter_btn.clicked.connect(self.clear_filters)
        button_layout.addWidget(self.clear_filter_btn)
        
        button_layout.addStretch()
        
        filter_layout.addLayout(button_layout, 2, 0, 1, 4)
        
        layout.addWidget(filter_group)
        
        # 加载筛选选项
        self.load_filter_options()
        
        return widget
    
    def create_bottom_widget(self):
        """创建下部分组件"""
        widget = QWidget()
        layout = QHBoxLayout(widget)
        
        # 左侧：资产列表
        left_widget = self.create_asset_list_widget()
        layout.addWidget(left_widget, 2)
        
        # 右侧：资产详情
        right_widget = self.create_asset_detail_widget()
        layout.addWidget(right_widget, 1)
        
        return widget
    
    def create_asset_list_widget(self):
        """创建资产列表组件"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 标题和操作按钮
        title_layout = QHBoxLayout()
        
        title_label = QLabel("资产列表")
        title_font = QFont()
        title_font.setBold(True)
        title_font.setPointSize(12)
        title_label.setFont(title_font)
        title_layout.addWidget(title_label)
        
        title_layout.addStretch()
        
        self.add_btn = QPushButton("新增资产")
        self.add_btn.clicked.connect(self.add_asset)
        title_layout.addWidget(self.add_btn)
        
        self.edit_btn = QPushButton("编辑资产")
        self.edit_btn.clicked.connect(self.edit_asset)
        self.edit_btn.setEnabled(False)
        title_layout.addWidget(self.edit_btn)
        
        self.delete_btn = QPushButton("删除资产")
        self.delete_btn.clicked.connect(self.delete_asset)
        self.delete_btn.setEnabled(False)
        title_layout.addWidget(self.delete_btn)
        
        layout.addLayout(title_layout)
        
        # 资产表格
        self.asset_table = QTableWidget()
        self.asset_table.setColumnCount(6)
        self.asset_table.setHorizontalHeaderLabels([
            "资产名称", "资产编码", "资产类型", "部门", "CPU/内存", "存储"
        ])
        
        # 设置表格属性
        header = self.asset_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(5, QHeaderView.ResizeToContents)
        
        self.asset_table.setSelectionBehavior(QTableWidget.SelectRows)
        self.asset_table.setSelectionMode(QTableWidget.SingleSelection)
        self.asset_table.itemSelectionChanged.connect(self.on_selection_changed)
        self.asset_table.itemDoubleClicked.connect(self.edit_asset)
        
        layout.addWidget(self.asset_table)
        
        return widget
    
    def create_asset_detail_widget(self):
        """创建资产详情组件"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 标题
        title_label = QLabel("资产详情")
        title_font = QFont()
        title_font.setBold(True)
        title_font.setPointSize(12)
        title_label.setFont(title_font)
        layout.addWidget(title_label)
        
        # 详情标签页
        self.detail_tabs = QTabWidget()
        layout.addWidget(self.detail_tabs)
        
        # 基本信息标签页
        basic_widget = QWidget()
        basic_layout = QVBoxLayout(basic_widget)
        
        self.basic_info_text = QTextEdit()
        self.basic_info_text.setReadOnly(True)
        basic_layout.addWidget(self.basic_info_text)
        
        self.detail_tabs.addTab(basic_widget, "基本信息")
        
        # 硬件信息标签页
        hardware_widget = QWidget()
        hardware_layout = QVBoxLayout(hardware_widget)
        
        self.hardware_info_text = QTextEdit()
        self.hardware_info_text.setReadOnly(True)
        hardware_layout.addWidget(self.hardware_info_text)
        
        self.detail_tabs.addTab(hardware_widget, "硬件信息")
        
        # 设备组成关系标签页
        composition_widget = QWidget()
        composition_layout = QVBoxLayout(composition_widget)
        
        self.composition_info_text = QTextEdit()
        self.composition_info_text.setReadOnly(True)
        composition_layout.addWidget(self.composition_info_text)
        
        self.detail_tabs.addTab(composition_widget, "设备组成")
        
        return widget
    
    def load_filter_options(self):
        """加载筛选选项"""
        try:
            # 加载资产类型
            asset_types = self.asset_service.get_asset_types()
            self.asset_type_combo.clear()
            self.asset_type_combo.addItem("全部")
            for asset_type in asset_types:
                self.asset_type_combo.addItem(asset_type['name'], asset_type['code'])
            
            # 加载部门
            departments = self.asset_service.get_departments()
            self.department_combo.clear()
            self.department_combo.addItem("全部")
            for dept in departments:
                self.department_combo.addItem(dept)
                
        except Exception as e:
            logger.error(f"加载筛选选项失败: {e}")
    
    def load_assets(self):
        """加载资产列表"""
        try:
            # 检查asset_table是否存在
            if not hasattr(self, 'asset_table'):
                if self._load_retry_count < self._max_retries:
                    self._load_retry_count += 1
                    logger.warning(f"asset_table 属性不存在，延迟加载数据 (重试 {self._load_retry_count}/{self._max_retries})")
                    # 延迟100ms后再次尝试
                    QTimer.singleShot(100, self.load_assets)
                    return
                else:
                    logger.error(f"asset_table 属性不存在，已达到最大重试次数 {self._max_retries}")
                    return
                
            self.status_message.emit("正在加载资产数据...")
            
            # 获取筛选条件
            filters = self.get_filter_conditions()
            
            # 获取资产数据
            assets = self.asset_service.get_all_assets(filters)
            self.current_assets = assets
            
            # 更新表格
            self.update_asset_table(assets)
            
            # 更新统计信息
            self.update_statistics()
            
            self.status_message.emit(f"已加载 {len(assets)} 个资产")
            
        except Exception as e:
            logger.error(f"加载资产数据失败: {e}")
            QMessageBox.critical(self, "错误", f"加载数据失败: {str(e)}")
            self.status_message.emit("加载数据失败")
    
    def get_filter_conditions(self) -> Dict[str, Any]:
        """获取筛选条件"""
        filters = {}
        
        # 资产类型
        if self.asset_type_combo.currentText() != "全部":
            index = self.asset_type_combo.currentIndex()
            if index > 0:
                filters['asset_type'] = self.asset_type_combo.itemData(index)
        
        # 部门
        if self.department_combo.currentText() != "全部":
            filters['department'] = self.department_combo.currentText()
        
        # 名称搜索
        name_search = self.name_search_edit.text().strip()
        if name_search:
            filters['asset_name'] = name_search
        
        # 用途搜索
        purpose_search = self.purpose_search_edit.text().strip()
        if purpose_search:
            filters['purpose_desc'] = purpose_search
        
        return filters
    
    def update_asset_table(self, assets: List[Dict[str, Any]]):
        """更新资产表格"""
        # 检查asset_table是否存在
        if not hasattr(self, 'asset_table'):
            logger.error("asset_table 属性不存在，可能UI还未完全初始化")
            return
            
        self.asset_table.setRowCount(len(assets))
        
        for row, asset in enumerate(assets):
            # 资产名称
            name_item = QTableWidgetItem(asset['asset_name'])
            name_item.setData(Qt.UserRole, asset['asset_id'])
            self.asset_table.setItem(row, 0, name_item)
            
            # 资产编码
            self.asset_table.setItem(row, 1, QTableWidgetItem(asset['asset_code']))
            
            # 资产类型
            type_name = self.asset_utils.get_asset_type_display(asset['asset_type'])
            self.asset_table.setItem(row, 2, QTableWidgetItem(type_name))
            
            # 部门
            department = asset.get('department', '未分配')
            self.asset_table.setItem(row, 3, QTableWidgetItem(department))
            
            # CPU/内存
            cpu = asset.get('cpu_cores', '-')
            memory = asset.get('memory_gb', '-')
            cpu_memory = f"{cpu}核/{memory}GB" if cpu != '-' and memory != '-' else f"{cpu}/{memory}"
            self.asset_table.setItem(row, 4, QTableWidgetItem(cpu_memory))
            
            # 存储
            storage = asset.get('storage_capacity', '-')
            storage_text = f"{storage}GB" if storage != '-' else storage
            self.asset_table.setItem(row, 5, QTableWidgetItem(storage_text))
    
    def update_statistics(self):
        """更新统计信息"""
        try:
            stats = self.asset_service.get_asset_statistics()
            
            # 总数
            self.total_count_label.setText(str(stats.get('total_count', 0)))
            
            # 类型分布
            type_stats = stats.get('by_type', {})
            type_text = ", ".join([f"{k}:{v}" for k, v in type_stats.items()])
            self.type_stats_label.setText(type_text if type_text else "无")
            
            # 部门分布
            dept_stats = stats.get('by_department', {})
            dept_text = ", ".join([f"{k}:{v}" for k, v in dept_stats.items()])
            self.dept_stats_label.setText(dept_text if dept_text else "无")
            
            # 硬件资源
            cpu = stats.get('total_cpu_cores', 0)
            memory = stats.get('total_memory_gb', 0)
            storage = stats.get('total_storage_capacity', 0)
            resource_text = f"CPU:{cpu}核/内存:{memory}GB/存储:{storage}GB"
            self.resource_stats_label.setText(resource_text)
            
        except Exception as e:
            logger.error(f"更新统计信息失败: {e}")
    
    def refresh_statistics(self):
        """刷新统计信息"""
        self.update_statistics()
    
    def apply_filters(self):
        """应用筛选条件"""
        self.load_assets()
    
    def clear_filters(self):
        """清除筛选条件"""
        self.asset_type_combo.setCurrentIndex(0)
        self.department_combo.setCurrentIndex(0)
        self.name_search_edit.clear()
        self.purpose_search_edit.clear()
        self.load_assets()
    
    def on_selection_changed(self):
        """选择改变事件"""
        # 检查asset_table是否存在
        if not hasattr(self, 'asset_table'):
            return
            
        selected_items = self.asset_table.selectedItems()
        has_selection = len(selected_items) > 0
        
        self.edit_btn.setEnabled(has_selection)
        self.delete_btn.setEnabled(has_selection)
        
        if has_selection:
            asset_id = selected_items[0].data(Qt.UserRole)
            self.show_asset_detail(asset_id)
        else:
            self.clear_asset_detail()
    
    def show_asset_detail(self, asset_id: str):
        """显示资产详情"""
        try:
            asset = self.asset_service.get_asset_by_id(asset_id)
            if not asset:
                return
            
            # 基本信息
            basic_info = f"""
资产ID: {asset['asset_id']}
资产名称: {asset['asset_name']}
资产编码: {asset['asset_code']}
资产类型: {self.asset_utils.get_asset_type_display(asset['asset_type'])}
型号: {asset.get('model', '无')}
部门: {asset.get('department', '未分配')}
用途描述: {asset.get('purpose_desc', '无')}
创建时间: {asset.get('create_time', '无')}
更新时间: {asset.get('update_time', '无')}
            """.strip()
            self.basic_info_text.setText(basic_info)
            
            # 硬件信息
            hardware_info = f"""
CPU核数: {asset.get('cpu_cores', '无')}
内存: {asset.get('memory_gb', '无')} GB
存储容量: {asset.get('storage_capacity', '无')} GB
硬盘数量: {asset.get('hard_disk_count', '无')}
硬盘规格: {asset.get('hard_disk_specs', '无')}
            """.strip()
            self.hardware_info_text.setText(hardware_info)
            
            # 设备组成关系
            composition = asset.get('device_composition', [])
            if composition:
                composition_text = "组成设备:\n"
                for comp_asset_id in composition:
                    comp_asset = self.asset_service.get_asset_by_id(comp_asset_id)
                    if comp_asset:
                        composition_text += f"- {comp_asset['asset_name']} ({comp_asset['asset_code']})\n"
            else:
                composition_text = "无设备组成关系"
            self.composition_info_text.setText(composition_text)
            
        except Exception as e:
            logger.error(f"显示资产详情失败: {e}")
    
    def clear_asset_detail(self):
        """清除资产详情"""
        self.basic_info_text.clear()
        self.hardware_info_text.clear()
        self.composition_info_text.clear()
    
    def add_asset(self):
        """新增资产"""
        dialog = AssetDialog(self)
        dialog.asset_saved.connect(self.on_asset_saved)
        dialog.exec_()
    
    def edit_asset(self):
        """编辑资产"""
        selected_items = self.asset_table.selectedItems()
        if not selected_items:
            return
        
        asset_id = selected_items[0].data(Qt.UserRole)
        dialog = AssetDialog(self, asset_id)
        dialog.asset_saved.connect(self.on_asset_saved)
        dialog.exec_()
    
    def delete_asset(self):
        """删除资产"""
        selected_items = self.asset_table.selectedItems()
        if not selected_items:
            return
        
        asset_id = selected_items[0].data(Qt.UserRole)
        asset_name = selected_items[0].text()
        
        reply = QMessageBox.question(
            self, "确认删除",
            f"确定要删除资产 '{asset_name}' 吗？\n\n注意：如果该资产有关联数据，将无法删除。",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            try:
                result = self.asset_service.delete_asset(asset_id)
                if result['success']:
                    QMessageBox.information(self, "成功", result['message'])
                    self.load_assets()
                else:
                    QMessageBox.warning(self, "失败", result['message'])
            except Exception as e:
                logger.error(f"删除资产失败: {e}")
                QMessageBox.critical(self, "错误", f"删除失败: {str(e)}")
    
    def on_asset_saved(self, asset_id: str):
        """资产保存事件"""
        self.load_assets()
    
    def export_assets(self):
        """导出资产数据"""
        try:
            filters = self.get_filter_conditions()
            data = self.asset_service.export_assets(filters)
            
            if not data:
                QMessageBox.information(self, "提示", "没有数据可导出")
                return
            
            # 这里可以实现导出到Excel的功能
            # 暂时显示导出数据量
            QMessageBox.information(self, "导出成功", f"已导出 {len(data)} 条资产数据")
            
        except Exception as e:
            logger.error(f"导出资产数据失败: {e}")
            QMessageBox.critical(self, "错误", f"导出失败: {str(e)}")